"""
Copyright (c) 2022 Huawei Technologies Co.,Ltd.

openGauss is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:

          http://license.coscl.org.cn/MulanPSL2

THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
"""
"""
Case Type   : 数据库系统
Case Name   : 套接字文件权限异常恢复，主停服，备升主
Create At   : 2020/07/27
@zou_jialiang0505328126
Description :
    1. 获取套接字文件路径
    2. 获取套接字文件名
    3. 修改套接字文件权限为不可读不可写
    4. 连接数据库
    5. 运行tpcc指令
    6. 恢复socket文件权限
    7. 连接数据库
    8. 备机failover
    9. 主备状态正常
    10. 连接数据库
    11. 切换后主节点运行tpcc指令
    12、还原主备
Expect      :
    1. 获取套接字文件路径成功
    2. 获取套接字文件名成功
    3. 修改套接字文件权限为不可读不可写成功
    4. 连接数据库，套接字方式连接异常
    5. 运行tpcc成功
    6. 恢复socket文件权限成功
    7. 连接数据库成功
    8. 备机failover成功
    9. 主备状态正常
    10. 连接数据库正常
    11. 切换后主节点运行tpcc成功
    12、还原主备成功
History     :
    modified：2021-4-22 by 5328113;状态结果查询方式变更，修改脚本；
    modified：2021-2-2 by 5328113;优化脚本，脚本内容与实际步骤不符，修改相关说明
        修改teardown中build调用方式，删除teardown断言信息
"""

import os
import unittest

from testcase.utils.Common import Common
from testcase.utils.CommonSH import *
from testcase.utils.Constant import Constant
from testcase.utils.Logger import Logger
from yat.test import Node
from yat.test import macro


class DbsysCase167(unittest.TestCase):
    nodes_tuple = ('PrimaryDbUser', 'Standby1DbUser', 'Standby2DbUser')

    @RestartDbCluster(*nodes_tuple)
    def setUp(self):
        self.log = Logger()
        self.log.info('----this is setup----')
        self.pri_sh = CommonSH('PrimaryDbUser')
        self.sta_1_sh = CommonSH('Standby1DbUser')
        self.sta_2_sh = CommonSH('Standby2DbUser')
        self.pri_dbuser = Node(node='PrimaryDbUser')
        self.pri_root = Node(node='PrimaryRoot')
        self.sta1_dbuser = Node(node='Standby1DbUser')
        self.sta1_root = Node(node='Standby1Root')
        self.com = Common()
        self.constant = Constant()
        self.file_name = ''
        self.log.info('----Opengauss_Reliability_Dbsys_Case167 start----')

    def test_main(self):
        self.log.info('----1. 获取套接字文件路径----')
        get_sql = 'show unix_socket_directory'
        file_path_msg = self.pri_sh.executDbSql(get_sql)
        self.log.info(file_path_msg)
        self.file_path = file_path_msg.split('\n')[2]
        self.log.info(self.file_path)

        self.log.info('----2. 获取套接字文件名----')
        get_file_list_cmd = f'ls -a {self.file_path}'
        self.log.info(get_file_list_cmd)
        file_list = self.pri_dbuser.sh(get_file_list_cmd).result()
        self.log.info(file_list)
        socket_file_name = ''
        for file in file_list.split():
            self.log.info(file)
            if (self.pri_dbuser.db_port not in file) or ('lock' in file):
                pass
            else:
                socket_file_name = file
        self.log.info(socket_file_name)

        self.file_name = os.path.join(self.file_path, socket_file_name)
        self.log.info('----3. 修改套接字文件权限为不可读不可写----')
        chmod_cmd = f'chmod 000 {self.file_name}'
        self.pri_root.sh(chmod_cmd).result()
        self.log.info(chmod_cmd)

        self.log.info('----4. 连接数据库----')
        self.log.info('----非socket连接数据库----')
        no_socket_connect_msg = self.pri_sh.nosocketConnect()
        self.log.info(no_socket_connect_msg)
        self.assertEqual(no_socket_connect_msg, '')
        self.log.info('----socket连接数据库----')
        socket_connect_msg = self.pri_sh.socket_connect(self.file_path)
        self.log.info(socket_connect_msg)
        self.assertIn(self.constant.FAILED_CONNECT_DB, socket_connect_msg)

        self.log.info('----5. 运行tpcc----')
        tpcc_result = self.com.startTPCC(self.pri_root, macro.TPCC_PATH)
        self.log.info('----' + tpcc_result + '----')
        self.log.info(tpcc_result)
        self.assertIn(self.constant.TPCC_SUCCESS_MSG, tpcc_result)

        self.log.info('----同步是否正常----')
        self.pri_sh.check_location_consistency('primary', 3)
        self.log.info('----查询主备状态----')
        status = self.pri_sh.getDbClusterStatus('status')
        self.assertTrue(status)

        self.log.info('----6. 恢复socket文件权限----')
        recover_cmd = f'chmod 700 {self.file_name}'
        self.log.info(recover_cmd)
        self.pri_root.sh(recover_cmd)

        self.log.info('----7. 连接数据库----')
        self.log.info('----非socket连接数据库----')
        no_socket_connect_msg = self.pri_sh.nosocketConnect()
        self.log.info(no_socket_connect_msg)
        self.assertEqual(no_socket_connect_msg, '')
        self.log.info('----socket连接数据库----')
        socket_connect_msg = self.pri_sh.socket_connect(self.file_path)
        self.log.info(socket_connect_msg)
        self.assertEqual(socket_connect_msg, '')

        self.log.info('----8. 备机failover----')
        self.log.info('----8.1、停止主机----')
        stop_msg = self.pri_sh.stopDbInstance()
        self.assertIn(self.constant.GS_CTL_STOP_SUCCESS_MSG, stop_msg)
        self.log.info('----8.2、备机进行failover----')
        success_msg = self.constant.FAILOVER_SUCCESS_MSG
        failover_result = self.sta_1_sh.executeGsctl('failover', success_msg)
        self.assertTrue(failover_result)
        self.log.info('----8.3、进行refresh----')
        refresh_msg = self.sta_1_sh.exec_refresh_conf()
        self.assertTrue(refresh_msg)
        self.log.info('----8.4、备机启动----')
        start_msg = self.pri_sh.startDbInstance('standby')
        self.assertIn(self.constant.RESTART_SUCCESS_MSG, start_msg)

        self.log.info('----查看主机query，同步是否正常----')
        self.sta_1_sh.check_location_consistency('primary', 3)
        self.log.info('----9、查询主备状态----')
        status = self.pri_sh.getDbClusterStatus('status')
        self.assertTrue(status)

        self.log.info('----10. 连接数据库----')
        self.log.info('----10.1、新主机非socket连接opengauss----')
        no_socket_connect_msg = self.sta_1_sh.nosocketConnect()
        self.log.info(no_socket_connect_msg)
        self.assertEqual(no_socket_connect_msg, '')

        self.log.info('----10.2、新主机socket连接opengauss----')
        socket_connect_msg = self.sta_1_sh.socket_connect(self.file_path)
        self.log.info(socket_connect_msg)
        self.assertEqual(socket_connect_msg, '')

        self.log.info('----11. 切换后主节点运行tpcc----')
        tpcc_result = self.com.startTPCC(self.sta1_root, macro.TPCC_PATH)
        self.log.info('----' + tpcc_result + '----')
        self.log.info(tpcc_result)
        self.assertIn(self.constant.TPCC_SUCCESS_MSG, tpcc_result)

        self.log.info('----查看主机query，同步是否正常----')
        self.sta_1_sh.check_location_consistency('primary', 3)
        self.log.info('----查询主备状态----')
        status = self.sta_1_sh.getDbClusterStatus('status')
        self.assertTrue(status)

        self.log.info('----12、还原主备----')
        success_msg = self.constant.SWITCH_SUCCESS_MSG
        switch_result = self.pri_sh.executeGsctl('switchover', success_msg)
        self.assertTrue(switch_result)
        refresh_msg = self.pri_sh.exec_refresh_conf()
        self.assertTrue(refresh_msg)
        self.log.info('----同步是否正常----')
        self.pri_sh.check_location_consistency('primary', 3)
        self.log.info('----查询主备状态----')
        status = self.pri_sh.getDbClusterStatus('status')
        self.assertTrue(status)

    def tearDown(self):
        self.log.info('----this is tearDown----')

        self.log.info('----恢复conf file权限----')
        chmod_cmd = f'chmod 700 {self.file_name}'
        self.pri_root.sh(chmod_cmd).result()
        self.log.info(chmod_cmd)

        host_name = self.pri_root.sh('hostname').result()
        if self.pri_sh.check_whether_need_switch(host_name):
            self.log.info('----恢复主备关系----')
            if self.pri_sh.check_whether_need_build():
                self.log.info('如果备机无法恢复，需要重建备机')
                self.pri_sh.executeGsctl('build',
                                         self.constant.REBUILD_SUCCESS_MSG)
            self.log.info('---进行主备切换---')
            success_msg = self.constant.SWITCHOVER_SUCCESS_MSG
            result = self.pri_sh.executeGsctl('switchover', success_msg)
            self.log.info(result)
            result = self.pri_sh.exec_refresh_conf()
            self.log.info(result)

        self.log.info('----Opengauss_Reliability_Dbsys_Case167 执行结束----')
